#ifndef __UI_H__
#define __UI_H__

#define CLEAR()         printf("\033[2J")           /*清除屏幕*/
#define MOVEUP(x)       printf("\033[%dA", (x))     /*上移光标*/
#define MOVEDOWN(x)     printf("\033[%dB", (x))     /*下移光标*/
#define MOVELEFT(y)     printf("\033[%dD", (y))     /*左移光标*/
#define MOVERIGHT(y)    printf("\033[%dC",(y))      /*右移光标*/
#define MOVETO(x,y)     printf("\033[%d;%dH", (x), (y))     /*定位光标*/
#define RESET_CURSOR()  printf("\033[H")            /*光标复位*/
#define HIDE_CURSOR()   printf("\033[?25l")         /*隐藏光标*/
#define SHOW_CURSOR()   printf("\033[?25h")         /*显示光标*/
#define UNDER_LINE      "\033[4m"                   /*下划线*/
#define RESET_COLOR     "\e[0m"

#define OPTION_MAX      (10)

#define UP			    (-106)
#define BELOW		    (-105)
#define LEFT		    (-104)
#define RIGHT		    (-103)
#define ENT			    (10)
#define	BACK		    (127)

#define BUTTON		    		(15)	/*页面按钮最多支持的数目*/
#define FRAME		    		(3)	    /*页面最多支持打印的边框数目*/
#define	MESSAGE		    		(30)	/*页面最多支持打印的信息个数*/
#define THE_PAGE_NUMBER			(10)	/*最多页面数*/
#define TRAIN_MESSAGE_NUMBER	(7)		/*火车票信息个数*/

#define BTN_USER_ID_SIZE        (7)
#define BTN_USER_PASSWD_SIZE    (7)
#define BTN_ADMIN_ID_SIZE       (1)
#define BTN_ADMIN_PASSWD_SIZE   (1)
#define BTN_NAME_SIZE           (19)
#define BTN_CITIZEN_ID_SIZE     (7)
#define BTN_PHONE_NUM_SIZE      (10)

#define BTN_ORIGIN_PLACE_SIZE       (19)
#define BTN_DESTINATION_SIZE        (19)
#define BTN_DEPARTURE_TIME_SIZE     (5)
#define BTN_ARRIVAL_TIME_SIZE       (5)
#define BTN_PRICE_SIZE              (3)
#define BTN_TICKET_NUM_SIZE         (3)
#define BTN_TRAIN_NUM_SIZE          (3)

enum button_options {
    ID = 0,
	PASSWORD,
	ADMIN_ID,
	ADMIN_PASSWORD,
    NAME,
    PHONE_NUM,
    CITIZEN_ID,
	MODIFY_USER_BTN,
	MODIFY_TICKET_BTN,
	ADD_TICKET_BTN,
	BUY_TICKET_BTN,
	RETURN_TICKET_BTN,
	AFFIRM,
    RETURN,
	TRAIN_NUM,
	ORIGIN_PLACE,
	DESTINATION,
	DEPARTURE_TIME,
	ARRIVAL_TIME,
	PRICE,
	TICKET_NUM,
	CHANGE_TRAIN_NUM,
	TRAIN_LIST
};

enum option_type {
   	HAVE_DATA = 0,
  	NO_DATA,
	CONCEAL_DATA,
	LIST
};

enum message_type {
	GENERAL_MESSAGE = 0,
	ERROR_MESSAGE
};

enum train_message_type {
	TRAIN_NUMBER_MSG = 0,
	ORIGIN_PLACE_MSG,
	DESTINATION_MSG,
	DEPARTURE_TIME_MSG,
	ARRIVAL_TIME_MSG,
	PRICE_MSG,
	TICKET_NUMBER_MSG
};

struct headline {
	char name[20];
	int serial_number;
	int place_x;
	int place_y;
};

struct train_list {
	int headline_amount;		/*标题个数*/
	int printf_line_number;		//信息打印行数
	int page_turning_x;			//翻页按钮位置<--于-->
	int page_turning_y;
	int number_of;				/*正在所处第几页*/
	int max_page;				/*最大页数*/
	int space_between;			/*纵向间距*/
	struct headline name[20];	//存储标题
	struct ui_print_ticket_data *page_number_head[10];	/*用于存储每一页头节点最多10页需要增加可以修改*/
};

struct button {
	char name[40];						/*按钮标题*/
	int number;							/*按钮编号*/
	int place_x;						/*按钮x轴位置*/
	int place_y;						/*按钮y轴位置*/
	int cursor_x;						/*光标移动*/
	int cursor_y;
	int type;							/*按钮类型*/
	char cache_data[30];				/*数据缓存区域*/
	int input_limit;					/* 限制输入长度 */
	struct train_list list_;
};

struct frame {
	char form[3];						/*边框的形状*/
	int origin_x;						/*边框初始x坐标位置*/
	int origin_y;						/*边框初始y坐标位置*/
	int longth;							/*边框长度*/
	int width;							/*边框宽度*/
};

struct message {
	char message[100];					/*打印信息*/
	int origin_x;						/*打印x轴位置*/
	int origin_y;						/*打印y轴位置*/
	int message_type;					/*信息类型*/
	int number;							/*错误信息编号*/
};

struct ui_print_ticket_data {
	char *train_message[TRAIN_MESSAGE_NUMBER];
    struct ui_print_ticket_data *next;
};

struct ui {
    int button_num;						    /*按钮数目*/
	struct button button[BUTTON];			/*按钮结构体*/
	int frame_num;						    /*边框数目*/
	struct frame rim[FRAME];				/*边框结构体*/
	int message_num;				        /*打印信息数目*/
	struct message message[MESSAGE];		/*打印信息结构体*/
	int button_select;						/*按钮选择*/
	struct ui *superstratun;				/*记录上级页面的地址，没有上层页面应该赋值NULL*/
};

struct input_data {
    int input_count;
    char input[100];
    int option_type;
};

extern void ui_init(struct ui *ui_data);
extern struct input_data *menu_control(struct ui *ui_data,
										struct ui_print_ticket_data *data,
										int error_number);

#endif